﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FacturIT.Service;
using FacturIT.BLL.Model.Company;
using FacturIT.BLL.Model.Helper;
using System.Configuration;
using System.Data.Linq;

namespace FacturIT.Service.Repositories.Company
{
    public class CompanyRepository : IRepository<BLL.Model.Company.Company, int>
    {
        public CompanyRepository()
        {
            DB = new CompanyManagementDataContext(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["DatabaseToUse"]].ConnectionString);
        }

        protected Table<BLL.Model.Company.Company> DT
        {
            get { return ((CompanyManagementDataContext)base.DB).Companies; }
        }

        public override BLL.Model.Company.Company Read(int id)
        {
            BLL.Model.Company.Company company = ReadByID(id);
            return company == null ? null : company;
        }
        public BLL.Model.Company.Company Read(string name)
        {
            return (from company in DT
                    where company.Name.ToLower().Equals(name.ToLower())
                    select company).FirstOrDefault();
        }

        public override IEnumerable<BLL.Model.Company.Company> ReadAll()
        {
            return from company in DT
                   orderby company.Name
                   select company;
        }

        public override IEnumerable<BLL.Model.Company.Company> ReadAll(params int[] ids)
        {
            return from company in DT
                   where ids.Contains(company.CompanyID)
                   select company;
        }
        internal IEnumerable<BLL.Model.Company.Company> ReadAll(List<int> assetIDs)
        {
            return from company in DT
                   where assetIDs.Contains(company.CompanyID)
                   select company;
        }
        

        public override BLL.Model.Company.Company Add(BLL.Model.Company.Company t)
        {
            DT.InsertOnSubmit(t);
            SaveChanges();
            return ReadByID(t.CompanyID);
        }

        public override bool Delete(BLL.Model.Company.Company t)
        {
            DT.DeleteOnSubmit(t);
            SaveChanges();
            return !Exists(t.CompanyID);
        }

        public override BLL.Model.Company.Company Update(BLL.Model.Company.Company t)
        {
            UpdateObject(ReadByID(t.CompanyID), t, false);
            SaveChanges();
            return ReadByID(t.CompanyID);
        }

        public override BLL.Model.Company.Company Duplicate(BLL.Model.Company.Company t)
        {
            return Add(Create(t.Name, t.Street, t.PostalCode, t.City, t.Country, t.Phone));
        }

        protected override BLL.Model.Company.Company ReadByID(int id)
        {
            return DT.SingleOrDefault(x => x.CompanyID == id);
        }

        protected override void UpdateObject(BLL.Model.Company.Company left, BLL.Model.Company.Company right, bool replaceID)
        {
            if (replaceID) left.CompanyID = right.CompanyID;
            left.Name = right.Name;
            left.Street = right.Street;
            left.PostalCode = right.PostalCode;
            left.City = right.City;
            left.Country = right.Country;
            left.Phone = right.Phone;
        }

        protected override IEnumerable<BLL.Model.Company.Company> ApplyOrdering(IEnumerable<BLL.Model.Company.Company> query, IDictionary<Func<BLL.Model.Company.Company, object>, Enum.Ordering> columns)
        {
            return OrderHelper.ApplyOrdering<BLL.Model.Company.Company, object>(query, columns, company => company.CompanyID);
        }

        protected BLL.Model.Company.Company Create(string name, string street, string postalcode, string city, string country, string phone)
        {
            return new BLL.Model.Company.Company()
            {
                Name = name,
                Street = street,
                PostalCode = postalcode,
                City = city,
                Country = country,
                Phone = phone,
            };
        }

        internal BLL.Model.Company.Company ReadCompany(int companyID)
        {
            return (from company in DT
                    where company.CompanyID == companyID
                    select company).FirstOrDefault();
        }

        internal IEnumerable<BLL.Model.Company.Company> ReadMyOwnedCompanies(int userID)
        {
            return from company in DT
                   where company.Owner == userID
                   select company;
        }

        internal IEnumerable<BLL.Model.Company.Company> ReadAllCompanies()
        {
            return from company in DT
                   select company;
        }

        internal BLL.Model.Company.Company ReadCompanyByName(string companyname)
        {
            return (from company in DT
                    where company.Name.ToLower().Equals(companyname.ToLower())
                    select company).FirstOrDefault();
        }
    }
}